﻿Option Strict On

Imports System.Collections.Generic
Imports System.Text
Imports System.Net.Sockets

Namespace Proxy
    ''' <summary>
    ''' Factory class for creating new proxy client objects.
    ''' </summary>
    ''' <remarks>
    ''' <code>
    ''' // create an instance of the client proxy factory
    ''' ProxyClientFactory factory = new ProxyClientFactory();
    '''        
    ''' // use the proxy client factory to generically specify the type of proxy to create
    ''' // the proxy factory method CreateProxyClient return an IProxyClient object
    ''' IProxyClient proxy = factory.CreateProxyClient(ProxyType.Http, "localhost", 6588);
    '''
    ''' // create a connection through the proxy to www.starksoft.com over port 80
    ''' System.Net.Sockets.TcpClient tcpClient = proxy.CreateConnection("www.starksoft.com", 80);
    ''' </code>
    ''' </remarks>
    Public Class ProxyClientFactory

        ''' <summary>
        ''' Factory method for creating new proxy client objects.
        ''' </summary>
        ''' <param name="type">The type of proxy client to create.</param>
        ''' <return>Proxy client object.</return>
        Public Function CreateProxyClient(ByVal type As ProxyType) As IProxyClient
            If type = ProxyType.None Then
                Throw New ArgumentOutOfRangeException("type")
            End If

            Select Case type
                Case ProxyType.Http
                    Return New HttpProxyClient()
                Case ProxyType.Socks4
                    Return New Socks4ProxyClient()
                Case ProxyType.Socks4a
                    Return New Socks4aProxyClient()
                Case ProxyType.Socks5
                    Return New Socks5ProxyClient()
                Case Else
                    Throw New ProxyException(String.Format("Unknown proxy type {0}.", type.ToString()))
            End Select
        End Function

        ''' <summary>
        ''' Factory method for creating new proxy client objects using an existing TcpClient connection object.
        ''' </summary>
        ''' <param name="type">The type of proxy client to create.</param>
        ''' <param name="tcpClient">Open TcpClient object.</param>
        ''' <return>Proxy client object.</return>
        Public Function CreateProxyClient(ByVal type As ProxyType, ByVal tcpClient As TcpClient) As IProxyClient
            If type = ProxyType.None Then
                Throw New ArgumentOutOfRangeException("type")
            End If

            Select Case type
                Case ProxyType.Http
                    Return New HttpProxyClient(tcpClient)
                Case ProxyType.Socks4
                    Return New Socks4ProxyClient(tcpClient)
                Case ProxyType.Socks4a
                    Return New Socks4aProxyClient(tcpClient)
                Case ProxyType.Socks5
                    Return New Socks5ProxyClient(tcpClient)
                Case Else
                    Throw New ProxyException(String.Format("Unknown proxy type {0}.", type.ToString()))
            End Select
        End Function

        ''' <summary>
        ''' Factory method for creating new proxy client objects.  
        ''' </summary>
        ''' <param name="type">The type of proxy client to create.</param>
        ''' <param name="proxyHost">The proxy host or IP address.</param>
        ''' <param name="proxyPort">The proxy port number.</param>
        ''' <return>Proxy client object.</return>
        Public Function CreateProxyClient(ByVal type As ProxyType, ByVal proxyHost As String, ByVal proxyPort As Integer) As IProxyClient
            If type = ProxyType.None Then
                Throw New ArgumentOutOfRangeException("type")
            End If

            Select Case type
                Case ProxyType.Http
                    Return New HttpProxyClient(proxyHost, proxyPort)
                Case ProxyType.Socks4
                    Return New Socks4ProxyClient(proxyHost, proxyPort)
                Case ProxyType.Socks4a
                    Return New Socks4aProxyClient(proxyHost, proxyPort)
                Case ProxyType.Socks5
                    Return New Socks5ProxyClient(proxyHost, proxyPort)
                Case Else
                    Throw New ProxyException(String.Format("Unknown proxy type {0}.", type.ToString()))
            End Select
        End Function

        ''' <summary>
        ''' Factory method for creating new proxy client objects.  
        ''' </summary>
        ''' <param name="type">The type of proxy client to create.</param>
        ''' <param name="proxyHost">The proxy host or IP address.</param>
        ''' <param name="proxyPort">The proxy port number.</param>
        ''' <param name="proxyUsername">The proxy username.  This parameter is only used by Socks4 and Socks5 proxy objects.</param>
        ''' <param name="proxyPassword">The proxy user password.  This parameter is only used Socks5 proxy objects.</param>
        ''' <return>Proxy client object.</return>
        Public Function CreateProxyClient(ByVal type As ProxyType, ByVal proxyHost As String, ByVal proxyPort As Integer, ByVal proxyUsername As String, ByVal proxyPassword As String) As IProxyClient
            If type = ProxyType.None Then
                Throw New ArgumentOutOfRangeException("type")
            End If

            Select Case type
                Case ProxyType.Http
                    Return New HttpProxyClient(proxyHost, proxyPort)
                Case ProxyType.Socks4
                    Return New Socks4ProxyClient(proxyHost, proxyPort, proxyUsername)
                Case ProxyType.Socks4a
                    Return New Socks4aProxyClient(proxyHost, proxyPort, proxyUsername)
                Case ProxyType.Socks5
                    Return New Socks5ProxyClient(proxyHost, proxyPort, proxyUsername, proxyPassword)
                Case Else
                    Throw New ProxyException(String.Format("Unknown proxy type {0}.", type.ToString()))
            End Select
        End Function

        ''' <summary>
        ''' Factory method for creating new proxy client objects.  
        ''' </summary>
        ''' <param name="type">The type of proxy client to create.</param>
        ''' <param name="tcpClient">Open TcpClient object.</param>
        ''' <param name="proxyHost">The proxy host or IP address.</param>
        ''' <param name="proxyPort">The proxy port number.</param>
        ''' <param name="proxyUsername">The proxy username.  This parameter is only used by Socks4 and Socks5 proxy objects.</param>
        ''' <param name="proxyPassword">The proxy user password.  This parameter is only used Socks5 proxy objects.</param>
        ''' <return>Proxy client object.</return>
        Public Function CreateProxyClient(ByVal type As ProxyType, ByVal tcpClient As TcpClient, ByVal proxyHost As String, ByVal proxyPort As Integer, ByVal proxyUsername As String, ByVal proxyPassword As String) As IProxyClient
            Dim c As IProxyClient = CreateProxyClient(type, proxyHost, proxyPort, proxyUsername, proxyPassword)
            c.TcpClient = tcpClient
            Return c
        End Function


    End Class

End Namespace